package org.example.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.example.entity.Query;
import org.example.entity.User;
import org.example.exception.MyException;
import org.example.service.UserService;
import org.example.utils.PasswordUtils;
import org.example.utils.Result;
import org.example.utils.ThreadLocalUtil;
import org.example.utils.sms.MathUtils;
import org.example.utils.sms.SmsUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController//返回json数据
@CrossOrigin//解决跨域问题
@RequestMapping("/wzz")
@Api(tags = "登录和注册")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private SmsUtils smsUtils;

    //登录
    @PostMapping("/login")
    public Result login(@RequestBody User user){
        User user1= userService.login(user);
        Map<String,Object> map=new HashMap<>();
        String token="";
        if(user1!=null){
            if (user1.getStatus()==0){
                throw new MyException("221","该用户已被禁用");
            }
            // 提取盐值
            String[] parts = user1.getPassword().split("\\$");// 使用正则表达式分割密码字符串，提取盐值
            String salt = parts[0];// 获取盐值
            // 使用提供的盐值和用户输入的明文密码生成待验证的加密密码
            String jm = PasswordUtils.encrypt(user.getPassword(), salt);// 使用盐值加密密码
            if (jm.equals(user1.getPassword())) {// 比较加密后的密码
                map.put("data",user1);
                map.put("msg","登录成功");
                //产生令牌 保存到redis 给前端
                token = UUID.randomUUID().toString();
                String json= JSONObject.toJSONString(user1); //将user对象转换为json字符串
                System.out.println(user1);
                stringRedisTemplate.opsForValue().set(token,json,60, TimeUnit.MINUTES); //将token(键)和user对象(值)存入redis
                map.put("token",token);
            }else {
                throw new MyException("222","密码错误");
            }
        }else {
            throw new MyException("223","用户不存在");
        }
        return new Result("200","调用成功",map);
    }

    //注册
    @PostMapping("/register")
    public Result register(@RequestBody User user){
        Map<String,Object> map=new HashMap<>();
        // 加密密码
        String encryptedPassword = PasswordUtils.encrypt(user.getPassword());
        user.setPassword(encryptedPassword);
        int row= userService.register(user);
        if (row>0){
            map.put("data",user);//将user对象存入map
        }else {
            map.put("code",444);
            map.put("data",null);
            map.put("msg","注册失败");
        }
        return new Result("200","注册成功",map);
    }

    //生成验证码
    @GetMapping("/sendCode")//发送验证码
    public Result sendCode(String phone){
        String code= MathUtils.random();//随机生成验证码
        boolean bo=false;
        try {
            stringRedisTemplate.opsForValue().set(phone,code,5, TimeUnit.MINUTES);//5分钟过期
            bo=smsUtils.sendMessage(phone,code);//发送短信
        }catch (Exception e){
            bo=false;
            throw new RuntimeException(e);
        }
        if (!bo){
            return new Result("444", "发送失败");
        }
        return new Result("200", "发送成功");
    }

    //验证码登录
    @GetMapping("/yz")//验证码验证
    public Result yz(String phone,String code){
        String code1=stringRedisTemplate.opsForValue().get(phone);//获取验证码
        User user= userService.getOne(new QueryWrapper<User>().eq("phone",phone));//查询用户信息
        Map<String,Object> map=new HashMap<>();
        String token="";
        if (Objects.equals(code1, code)){
            if (user!=null){
                map.put("data",user);//将user对象存入map
                //产生令牌 保存到redis 给前端
                token = UUID.randomUUID().toString();
                String json= JSONObject.toJSONString(user); //将user对象转换为json字符串
                System.out.println(user);
                stringRedisTemplate.opsForValue().set(token,json,60, TimeUnit.MINUTES); //将token(键)和user对象(值)存入redis
                return new Result("200","登录成功",map);
            }else {
                return new Result("444","登录失败",map);
            }
        }else {
            throw new MyException("444","验证码错误");
        }
    }

    //注册时填写身份信息
    @PostMapping("/tx")
    public Result tx(@RequestBody User user){
        int row=userService.tx(user);
        Map<String,Object> map=new HashMap<>();
        if (row>0){
            map.put("code",200);
            map.put("data",user);
            map.put("msg","身份信息填写成功");
        }else {
            map.put("code",444);
            map.put("data",null);
            map.put("msg","身份信息填写失败");
        }
        return new Result("222","身份信息填写成功",map);
    }

    //判断手机号是否已经存在
    @GetMapping("/pd")
    public Result pd(String phone){
        QueryWrapper queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("phone",phone);
        User user=userService.getOne(queryWrapper);
        if (user!=null){
            throw new MyException("444","手机号已经注册");
        }
        return new Result("222","手机号未注册");
    }

    @GetMapping("/get-user-info")
    @ApiOperation("获取当前登录用户信息")
    public Result getUserInfo(){
        User user = userService.getById(ThreadLocalUtil.getCurrentId());
        if (user==null){
            throw new MyException("200","查询失败");
        }
        return new Result("200","查询成功",user);
    }

    //根据用户id查询用户信息
    @GetMapping("/get-user-info-by-id")
    @ApiOperation("根据用户id查询用户信息")
    public Result getUserInfoById(@RequestParam("id") int id){
        User user = userService.getById(id);
        if (user==null){
            throw new MyException("200","查询失败");
        }else {
            return new Result("200","查询成功",user);
        }
    }

    //根据用户id修改用户信息
    @PostMapping("/update-user-info")
    @ApiOperation("根据用户id修改用户信息")
    public Result updateUserInfo(@RequestBody User user){
            System.out.println("1111111111111111111111111");
            System.out.println(user.toString());
         int row=userService.updateUserByUsername(user);
        if (row>0){
            return new Result("200","修改成功");
        }else {
            return new Result("444","修改失败");
        }
    }
}
